using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spinning.Spinning.Interface;
using Spinning.Spinning.Entity.Particle;
using Microsoft.Xna.Framework;

namespace Spinning.Spinning.Level
{
    public abstract class ParticleLuncher : IUpdateHandler
    {
       public List<IParticle> Particles { get; set; }
        List<IParticle> AliveParticles { get; set; }
       public List<Rectangle> Areas { get;protected set; }
        int _counter;
        protected Random random = new Random();
        public bool Pause { get; set; }
        public bool Repeat { get; set; }
        public int ParticleMax { get; set; }
        public int ParticleMin { get; set; }
        public int Capacity { get; protected set; }
        int _particleCount;
        public int Rate { get; set; }

        public ParticleLuncher(int capacity)
        {
            this.Capacity = capacity;
            Particles = new List<IParticle>();
            AliveParticles = new List<IParticle>();
            Areas = new List<Rectangle>();
           // GenerateParticles();
            Reset();
        }

        protected void GenerateParticles()
        {
            for (int i = 0; i < Capacity; i++)
            {
                IParticle p = GenerateParticle();
                p.ParticlePosition = new Vector2(-2000 - 300 * i, -2000);
                Particles.Add(p);
            }
        }

        public void OnUpdate(Microsoft.Xna.Framework.GameTime gameTime)
        {
            if (!Pause)
            {
                _counter++;

                if (_counter % Rate == 0)
                {
                    for (int i = 0; i < Particles.Count; i++)
                    {
                        IParticle p = Particles[i];
                        if (p.isDead)
                        {
                            AliveParticles.Remove(p);
                            p.Reset();
                            p.ParticlePosition = new Vector2(-2000 - 300 * i, -2000);
                        }
                    }

                    int ps = random.Next(ParticleMin, ParticleMax);
                    for (int i = 0; i < ps; i++)
                    {
                        if (AliveParticle() < ParticleMax)
                        {
                            int area = random.Next(Areas.Count);
                            Rectangle r = Areas[area];
                            if (r != null)
                            {
                                int xMax = r.Right, yMax = r.Bottom, xMin = r.Left, yMin = r.Top;
                                int pX = random.Next(xMin, xMax);
                                int pY = random.Next(yMin, yMax);
                                Vector2 pos = new Vector2(pX, pY);
                                IParticle p = Particles[_particleCount];
                                ShotParticle(p, pos);
                                AliveParticles.Add(p);
                                _particleCount = (_particleCount + 1) % Particles.Count;
                            }
                        }
                    }
                }
            }
        }

        protected abstract void ShotParticle(IParticle particle, Vector2 pos);
        protected abstract IParticle GenerateParticle();


        public void Reset()
        {
            _counter = 0;
            _particleCount = 0;
            Pause = false;
            Repeat = true;
            ParticleMax = 3;
            ParticleMin = 0;
            Rate = 5;
        }

        protected int AliveParticle()
        {
            return AliveParticles.Count;
        }
    }
}
